home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
cawf404.zip
/
pass2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-07
|
21KB
|
844 lines
/*
* pass2.c - cawf(1) pass 2 function
*/
/*
* Copyright (c) 1991 Purdue University Research Foundation,
* West Lafayette, Indiana 47907. All rights reserved.
*
* Written by Victor A. Abell <abe@mace.cc.purdue.edu>, Purdue
* University Computing Center. Not derived from licensed software;
* derived from awf(1) by Henry Spencer of the University of Toronto.
*
* Permission is granted to anyone to use this software for any
* purpose on any computer system, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The author is not responsible for any consequences of use of
* this software, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either
* by explicit claim or by omission. Credits must appear in the
* documentation.
*
* 3. Altered versions must be plainly marked as such, and must not
* be misrepresented as being the original software. Credits must
* appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "cawf.h"
#include <ctype.h>
/*
* Pass2(line) - process the nroff requests in a line and break
* text into words for pass 3
*/
void
Pass2(line)
unsigned char *line;
{
int brk; /* request break status */
unsigned char buf[MAXLINE]; /* working buffer */
unsigned char c; /* character buffer */
double d; /* temporary double */
double exscale; /* expression scaling factor */
double expr[MAXEXP]; /* expressions */
unsigned char exsign[MAXEXP]; /* expression signs */
int i, j; /* temporary indexes */
int inword; /* word processing status */
int nexpr; /* number of expressions */
unsigned char nm[4], nm1[4]; /* names */
int nsp; /* number of spaces */
unsigned char op; /* expression term operator */
unsigned char opstack[MAXSP]; /* expression operation stack */
unsigned char period; /* end of word status */
unsigned char *s1, *s2, *s3; /* temporary string pointers */
double sexpr[MAXEXP]; /* signed expressions */
int sp; /* expression stack pointer */
unsigned char ssign; /* expression's starting sign */
double tscale; /* term scaling factor */
double tval; /* term value */
double val; /* term value */
double valstack[MAXSP]; /* expression value stack */
unsigned char xbuf[MAXLINE]; /* expansion buffer */
if (line == NULL) {
/*
* End of macro expansion.
*/
Pass3(DOBREAK, (unsigned char *)"need", 4, NULL, 999);
return;
}
/*
* Adjust line number.
*/
if (Lockil == 0)
P2il++;
/*
* Empty line - "^[ \t]*$" or "^\\\"".
*/
if (regexec(Pat[6].pat, line)
|| strncmp((char *)line, "\\\"", 2) == 0) {
Pass3(DOBREAK, (unsigned char *)"space", 5, NULL, 0);
return;
}
/*
* Line begins with white space.
*/
if (*line == ' ' || *line == '\t') {
Pass3(DOBREAK, (unsigned char *)"flush", 5, NULL, 0);
Pass3(0, (unsigned char *)"", 0, NULL, 0);
}
if (*line != '.' && *line != '\'') {
/*
* Line contains text (not an nroff request).
*/
if (Font[0] == 'R' && Backc == 0 && Aftnxt == NULL
&& regexec(Pat[7].pat, line) == 0) {
/*
* The font is Roman, there is no "\\c" or "after next"
* trap pending and and the line has no '\\', '\t', '-',
* or " " (regular expression "\\|\t|-| ").
*
* Output each word of the line as "<length> <word>".
*/
for (s1 = line;;) {
while (*s1 && *s1 == ' ')
s1++;
if (*s1 == '\0')
break;
for (s2 = s1, s3 = buf; *s2 && *s2 != ' ';)
*s3++ = Trtbl[(int)*s2++];
*s3 = '\0';
Pass3((s2 - s1), buf, (s2 - s1), NULL, 0);
s1 = *s2 ? ++s2 : s2;
}
/*
* Line terminates with punctuation and optional
* bracketing (regular expression "[.!?:][\])'\"*]*$").
*/
if (regexec(Pat[8].pat, line))
Pass3(NOBREAK, (unsigned char *)"gap", 3,
NULL, 2);
if (Centering > 0) {
Pass3(DOBREAK,(unsigned char *)"center", 6,
NULL, 0);
Centering--;
} else if (Fill == 0)
Pass3(DOBREAK, (unsigned char *)"flush", 5,
NULL, 0);
return;
}
/*
* Line must be scanned a character at a time.
*/
inword = nsp = 0;
period = '\0';
for (s1 = line;; s1++) {
/*
* Space or TAB causes state transition.
*/
if (*s1 == '\0' || *s1 == ' ' || *s1 == '\t') {
if (inword) {
if (!Backc) {
Endword();
Pass3(Wordl, Word, Wordx,
NULL, 0);
if (Uhyph) {
Pass3(NOBREAK,
(unsigned char *)"nohyphen",
8, NULL, 0);
}
}
inword = 0;
nsp = 0;
}
if (*s1 == '\0')
break;
} else {
if (inword == 0) {
if (Backc == 0) {
Wordl = Wordx = 0;
Uhyph = 0;
}
Backc = 0;
inword = 1;
if (nsp > 1) {
Pass3(NOBREAK,
(unsigned char *)"gap",
3, NULL, nsp);
}
}
}
/*
* Process a character.
*/
switch (*s1) {
/*
* Space
*/
case ' ':
nsp++;
period = '\0';
break;
/*
* TAB
*/
case '\t':
Pass3(NOBREAK, (unsigned char *)"tabto", 5,
NULL, 0);
nsp = 0;
period = '\0';
break;
/*
* Hyphen if word is being assembled
*/
case '-':
if (Wordl <= 0
|| (Wordl == 1 && Word[Wordx - 1] == '-'))
goto ordinary_char;
if ((i = Findhy(NULL, 0, 0)) < 0) {
Error(WARN, LINE, " no hyphen for font ",
(char *)Font);
return;
}
Endword();
Pass3(Wordl, Word, Wordx, NULL, Hychar[i].len);
Pass3(NOBREAK, (unsigned char *)"userhyphen",
10, Hychar[i].str, Hychar[i].len);
Wordl = Wordx = 0;
period = '\0';
Uhyph = 1;
break;
/*
* Backslash
*/
case '\\':
s1++;
switch(*s1) {
/*
* Comment - "\\\""
*/
case '"':
while (*(s1+1))
s1++;
break;
/*
* Change font - "\\fN"
*/
case 'f':
s1 = Asmcode(&s1, nm);
if (nm[0] == 'P') {
Font[0] = Prevfont;
break;
}
for (i = 0; Fcode[i].nm; i++) {
if (Fcode[i].nm == nm[0])
break;
}
if (Fcode[i].nm == '\0'
|| nm[1] != '\0') {
Error(WARN, LINE, " unknown font ",
(char *)nm);
break;
}
if (Fcode[i].status != '1') {
Error(WARN, LINE,
" font undefined ", (char *)nm);
break;
} else {
Prevfont = Font[0];
Font[0] = nm[0];
}
break;
/*
* Positive horizontal motion - "\\h\\n(NN" or
* "\\h\\nN"
*/
case 'h':
if (s1[1] != '\\' || s1[2] != 'n') {
Error(WARN, LINE,
" no \\n after \\h", NULL);
break;
}
s1 +=2;
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0)
goto unknown_num;
if ((j = Numb[i].val) < 0) {
Error(WARN, LINE, " \\h < 0 ",
NULL);
break;
}
if (j == 0)
break;
if ((strlen((char *)s1+1) + j + 1)
>= MAXLINE)
goto line_too_long;
for (s2 = &xbuf[1]; j; j--)
*s2++ = ' ';
(void) strcpy((char *)s2, (char *)s1+1);
s1 = xbuf;
break;
/*
* Save current position in register if "\\k<reg>"
*/
case 'k':
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0)
i = Findnum(nm, 0, 1);
Numb[i].val =
(int)((double)Outll * Scalen);
break;
/*
* Interpolate number - "\\n(NN" or "\\nN"
*/
case 'n':
s1 = Asmcode(&s1, nm);
if ((i = Findnum(nm, 0, 0)) < 0) {
unknown_num:
Error(WARN, LINE,
" unknown number register ",
(char *)nm);
break;
}
(void) sprintf((char *)buf, "%d"